home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1993 April
/
CICA MS Windows - April 1993.iso
/
unzipped
/
programr
/
bcpp
/
mfc_bc
/
mfc_bc.txt
Wrap
Text File
|
1992-07-10
|
19KB
|
788 lines
Using Microsoft Foundation Classes
with
Borland C++ 3.1
Prepared by:
Language Business Unit
Borland International
1800 Green Hills Road
PO Box 660001
Scotts Valley, CA 95067-0001
Table of Contents
Table of Contents i
Overview 1
Changes to MFC 2
Changes to SRC\VALIDADD.CPP 2
Changes to SRC\DOSIO_.H 3
Changes to SRC\OLEPTR_.H 3
Changes to SRC\FILE.CPP 4
Changes to SRC\WINDOW.CPP 4
Changes to SRC\WINDLGS.CPP 5
Changes to SRC\OBJECT.CPP 6
Changes to the Build Process 7
Preparing for the Build Process 7
Changes to SRC\MAKEFILE 7
Debug Information and TASM 11
Memory Model Issues 12
Building with 386^Max 12
Building the Example Programs 13
Changes to the Build Process 13
Building An Example: ABOUT2 13
Changes to SAMPLES|ABOUT2\MAKEFILE 13
Changes to SAMPLES\ABOUT2\ABOUT2.H 14
Changes to Other Example Programs 14
Changes to SAMPLES\CTRLTEST\WCLSTEST.CPP 14
Changes to SAMPLES\CTRLTEST\PAREDIT2.CPP 15
Changes to SAMPLES\CTRLTEST\FEATPEN.CPP 15
Changes to SAMPLES\CTRLTEST\CUSTLIST.CPP 15
Overview
This document describes how to build and use Microsoft Foundation Class (MFC)
programs with Borland C++ 3.1. This document is divided into several sections. The
first describes changes to make to the MFC source files; the second, changes and
suggestions for the build process; and the final section explores compiling an example
providing with Microsoft C/C++ 7.0.
The changes described in this document are necessary for several reasons. Some relate to
non-standard syntax that Microsoft uses in their C++ compiler, while others relate to
differences in assembly language extensions and makefile conventions.
If you are using MFC for your Windows programs, you will find many advantages in
using Borland C++ 3.1 instead of Microsoft C/C++ 7.0:
* Borland provides far faster development times, with its lightning fast compiles.
* Borland provides a Windows hosted IDE.
* Borland provides more sophisticated Windows tools, such as Resource Workshop,
WinSight, and WinSpector.
* Borland provides a far more robust, compliant implementation of C++.
* Borland provides templates and other advanced C++ features.
* Borland provides automatic, safe precompiled headers and a smart project manager.
If you are interested in a more detailed technical comparison of Borland C++ 3.1 and
Microsoft C/C++ 7.0, be sure to ask for our technical whitepaper: "Borland C++ 3.1 &
Application Frameworks v. Microsoft C/C++ 7.0, An Expose".
Changes to MFC
This section describes the various changes you will need to make to the MFC source
code. Note that the line numbers mentioned are based on the version of MFC in the first
shipping packages of Microsoft C/C++ 7.0. The actual line numbers are subject to
change should Microsoft provide interim versions of MFC. Note further that any line
number references assume that you have made all previously mentioned changes to the
particular file.
Changes to SRC\VALIDADD.CPP
1. Add the following lines at the top of the file:
#ifdef __TURBOC__
#pragma inline
#endif
2. Because "asm" in not a valid keyword within an existing inline asm statement in
Borland C++ 3.1, you need to change the _asm _emit's to db's in the following
manner:
#ifdef __TURBOC__
db 0x66
#else
_asm _emit 0x66
#endif
3. Because Borland C++ 3.1 doesn't accept inline asm labels, you need to make the
following labels into C++ labels:
skip_write_test
skip_range_test
done
For example, instead of leaving the label skip_write_test in an inline asm block as
illustrated below,
jnz done
skip_write_test:
close the inline asm block, then open another after the label.
jnz done
}
skip_write_test:
_asm {
The label done needs a semicolon after it as follows:
}
skip_range_test:
_asm {
inc word ptr bValid
}
done:
;
}
else
4. The comparison:
cmp bReadWrite, 0
needs a type override. You need to change it to
cmp word ptr bReadWrite, 0
There are 2 occurrences of this statement in the file. Also, the increment:
inc bValid
needs a type override. You need to change it to
inc word ptr bValid
There are also 2 occurrences of this statement in SRC\VALIDADD.CPP.
5. Borland C++ 3.1 doesn't allow assembler-style comments in inline assembler, so you
should change all such comments to C++ style comments.
Changes to SRC\DOSIO_.H
1. Change line 33 from:
#define DOSCALL call DOS3Call
to
#define DOSCALL call far ptr DOS3Call
Changes to SRC\OLEPTR_.H
1. Because Borland C++ 3.1 does not allow Microsoft-style based pointers, you should
change line 17 from:
ASSERT(_AFX_FP_SEG(lp) == _segname("_DATA"));
to
#ifndef __TURBOC__
ASSERT(_AFX_FP_SEG(lp) == _segname("_DATA"));
#endif
Changes to SRC\FILE.CPP
1. Add the following lines at the top of the file:
#ifdef __TURBOC__
#pragma inline
#endif
2. Replace line 68 with the lines:
}
__seek_err:
_asm {
3. Replace line 87 with the lines:
}
__rename_err:
_asm {
4. Replace line 106 with the lines:
}
__remove_err:
_asm {
5. Replace line 129 with the lines:
}
__lock_err1:
_asm {
Changes to SRC\WINDOW.CPP
The function FindMessageEntry has inline assembler statements which Borland
C++ 3.1 does not recognize. You should replace this function with the following one,
which is compatible with both MSC/C++ 7.0 and Borland C++ 3.1.
static CMessageEntry FAR* NEAR
FindMessageEntry(CMessageEntry FAR* lpEntry, UINT nMsg, UINT nID)
{
_asm {
LES BX,lpEntry
MOV AX,nMsg
MOV DX,nID
}
__loop:
_asm {
MOV CX,WORD PTR ES:[BX+4] // nSig (0 =>
end)
JCXZ __failed
CMP AX,WORD PTR ES:[BX] // nMessage
JE __found_1
}
__next:
#ifdef __TURBOC__
static const int CMESSAGEENTRYSIZE = sizeof(CMessageEntry);
_asm {
ADD BX,CMESSAGEENTRYSIZE
JMP __loop
}
#else
_asm {
ADD BX,SIZE CMessageEntry
JMP __loop
}
#endif
__found_1:
_asm {
CMP DX,WORD PTR ES:[BX+2] // nID
JNE __next
// found a match
MOV WORD PTR lpEntry,BX
MOV WORD PTR lpEntry+2,ES
JMP __end
}
__failed:
_asm {
XOR AX,AX
MOV WORD PTR lpEntry,AX
MOV WORD PTR lpEntry+2,AX
}
__end:
return lpEntry;
}
Changes to SRC\WINDLGS.CPP
1. Line 705 contains a syntax error that MSC/C++ 7.0 does not detect. You need to
change line 705 from:
700: BOOL
701: CFindReplaceDialog::Create(BOOL bFindDialogOnly,
702: LPCSTR lpszFindWhat,
703: LPCSTR lpszReplaceWith /* = NULL */,
704: DWORD dwFlags /* = FR_DOWN */,
705: CWnd* pParentWnd ) : CDialog((UINT)0, pParentWnd)
706: {
^
the syntax error is here
to
700: BOOL
701: CFindReplaceDialog::Create(BOOL bFindDialogOnly,
702: LPCSTR lpszFindWhat,
703: LPCSTR lpszReplaceWith /* = NULL */,
704: DWORD dwFlags /* = FR_DOWN */,
705: CWnd* pParentWnd ) // : CDialog((UINT)0, pParentWnd)
706: {
Changes to SRC\OBJECT.CPP
1. The function AfxNewHandler on line 179 is prototyped incorrectly to be used as a
new handler. You should replace it with:
void cdecl AfxNewHandler(void)
{
// AFX memory allocation will never return "NULL" it will always
throw
// a memory exception instead
AfxThrowMemoryException();
}
Changes to the Build Process
This section describes changes you will need to make to your build process in order to
build MFC applications. It covers changes to the makefile as well as particulars relating
to memory models and DPMI servers.
Preparing for the Build Process
When building the MFC class library with Borland C++ 3.1, you must use Borland's
MAKE utility. When you invoke MAKE, you need to specify all the switches you would
normally use with NMAKE and append these two options:
MAKE ...normal options... -D__TURBOC__ -N
Since MSC/C++ 7.0 requires the INCLUDE and LIB environment variables to be set,
while Borland C++ 3.1 does not, you will need to create a TURBOC.CFG file that
defines these paths. Also, you will need to define some macros to control the building of
the MFC class library.
For example, if you installed Borland C++ 3.1 in C:\BORLANDC and MSC/C++ 7.0 in
C:\C700, your TURBOC.CFG file would look like this:
-Ic:\borlandc\include ; Standard headers
-Ic:\c700\mfc\include ; AFX headers
-Lc:\borlandc\lib ; Standard libraries
-Lc:\c700\mfc\lib ; MFC class libs
-D__MSC ; Tells std headers to allow MS bugs
-DBASED_CODE ; Don't use handle-based pointers
-D_asm=asm ; MS uses _asm, Borland uses asm
-D_stat=stat
The default optimization options for compiling MFC with C/C++ 7.0 are /Oselg. You
can use these options with Borland C++ 3.1, or you can compile with -O2 -po for fastest
code and -O1 -po for smallest code.
Changes to SRC\MAKEFILE
Note: all line number references that follow assume that you have made all previously
mentioned changes to the file.
1. Replace lines 47-48 with the lines:
!ifdef __TURBOC__
CPP=bcc
CC=bcc
!else
CPP=cl
CC=cl
!endif
2. Replace line 84 with the lines:
!ifdef __TURBOC__
DEBUGOPTS=/Od /N
!else
DEBOPTS=/Odr /f
!endif
3. Replace line 96 with the lines:
!ifdef __TURBOC__
DEBOPTS=$(DEBOPTS) /v
!else
DEBOPTS=$(DEBOPTS) /Zi
!endif
4. Replace line 105 with the lines:
!ifdef __TURBOC__
CVEXTRA=/v
!else
CVEXTRA=/Zi
!endif
5. Replace lines 112-128 with the lines:
!if "$(MODEL)"=="s" || "$(MODEL)"=="S" || "$(MODEL)"==""
!ifdef __TURBOC__
CL_MODEL=/ms /D_M_I86SM
!else
CL_MODEL=/AS
!endif
!else
!if "$(MODEL)"=="m" || "$(MODEL)"=="M"
!ifdef __TURBOC__
CL_MODEL=/mm /D_M_I86MM
!else
CL_MODEL=/AM
!endif
!else
!if "$(MODEL)"=="c" || "$(MODEL)"=="C"
!ifdef __TURBOC__
CL_MODEL=/mc /D_M_I86CM
!else
CL_MODEL=/AC
!endif
!else
!if "$(MODEL)"=="l" || "$(MODEL)"=="L"
!ifdef __TURBOC__
CL_MODEL=/ml /D_M_I86LM
!else
CL_MODEL=/AL
!endif
!else
!error MODEL must be one of S, M, C, L.
!endif
!endif
!endif
!endif
6. Replace lines 155-157 with the lines:
!ifdef __TURBOC__
TARGOPTS=/WSE /OW /2
MKWIN=1
EXPFLAG=/WSE
!else
TARGOPTS=/GA /GEs /G2
MKWIN=1
EXPFLAG=/GEe
!endif
7. Replace line 184 with the lines:
!ifdef __TURBOC__
CL_OPT=/w /a- $(DEBOPTS) $(TARGOPTS) $(OPT)
!else
CL_OPT=/W3 /Zp $(DEBOPTS) $(TARGOPTS) $(OPT)
!endif
8. Replace lines 196-199 with the lines:
!ifdef __TURBOC__
TARGDEFS=/D_WINDOWS
TARGOPTS=/WDE /2 /D_WINDLL
!else
CL_MODEL=$(CL_MODEL)w
TARGDEFS=/D_WINDOWS
TARGOPTS=/GD /G2
# /GD will define _WINDLL
!endif
9. Replace line 252 with the lines:
!ifdef __TURBOC__
CPPFLAGS=$(CPPFLAGS) /H=$(PCH_FILE)
!else
CPPFLAGS=$(CPPFLAGS) /Yu /Fp$(PCH_FILE)
!endif
10. Replace lines 264-271 with the lines:
!ifdef __TURBOC__
.cpp{$D}.obj:
$(CPP) @<<
$(CPPFLAGS) /c /o$@ $<
<<
.c{$D}.obj:
$(CC) @<<
$(CFLAGS) /c /o$@ $<
<<
!else
.cpp{$D}.obj:
$(CPP) @<<
$(CPPFLAGS) /c /Fo$@ $<
<<
.c{$D}.obj:
$(CC) @<<
$(CFLAGS) /c /Fo$@ $<
<<
!endif
11. Replace lines 310-312 with the lines:
!ifdef __TURBOC__
$(CPP) @<<
/c /H=$(PCH_FILE) $(CL_STANDARD) $(CL_MODEL) $(CL_OPT)
$(DEFS) $(CVEXTRA) /c /o$D\object.obj object.cpp
<<
!else
$(CPP) @<<
/c /Yc /Fp$(PCH_FILE) $(CL_STANDARD) $(CL_MODEL) $(CL_OPT)
$(DEFS) $(CVEXTRA) /c /Fo$D\object.obj object.cpp
<<
!endif
12. Replace lines 325-338 with the lines:
!ifdef __TURBOC__
!if "$(CODEVIEW)"=="2"
$D\memory.obj : memory.cpp
$(CPP) @<<
$(CPPFLAGS) $(CVEXTRA) /c /o$D\memory.obj memory.cpp
<<
!ifdef MKWIN
$D\winmain.obj : winmain.cpp
$(CPP) @<<
$(CPPFLAGS) $(CVEXTRA) /c /o$D\winmain.obj winmain.cpp
<<
$D\window.obj : window.cpp
$(CPP) @<<
$(CPPFLAGS) $(CVEXTRA) /c /o$D\window.obj window.cpp
<<
$D\winapp.obj : winapp.cpp
$(CPP) @<<
$(CPPFLAGS) $(CVEXTRA) /c /o$D\winapp.obj winapp.cpp
<<
!endif
!endif
!else
!if "$(CODEVIEW)"=="2"
$D\memory.obj : memory.cpp
$(CPP) @<<
$(CPPFLAGS) $(CVEXTRA) /c /Fo$D\memory.obj memory.cpp
<<
!ifdef MKWIN
$D\winmain.obj : winmain.cpp
$(CPP) @<<
$(CPPFLAGS) $(CVEXTRA) /c /Fo$D\winmain.obj winmain.cpp
<<
$D\window.obj : window.cpp
$(CPP) @<<
$(CPPFLAGS) $(CVEXTRA) /c /Fo$D\window.obj window.cpp
<<
$D\winapp.obj : winapp.cpp
$(CPP) @<<
$(CPPFLAGS) $(CVEXTRA) /c /Fo$D\winapp.obj winapp.cpp
<<
!endif
!endif
!endif
13. Replace lines 378-380 with the following lines:
!ifdef __TURBOC__
$(CPP) @<<
$(CPPFLAGS) $(EXPFLAG) /c /o$D\version.obj version.cpp
<<
!else
$(CPP) @<<
$(CPPFLAGS) $(EXPFLAG) /c /Fo$D\version.obj version.cpp
<<
!endif
14. Replace lines 394-400 with the following lines:
!ifdef __TURBOC__
tlib /P128 @<<
..\lib\$(GOAL) &
-+$(OBJS:.obj =.obj -+)
<<
!else
lib /PAGESIZE:128 @<<
..\lib\$(GOAL)
y
$(OBJS)
nul
;
<<
!endif
15. Replace all occurences of $D with $(D)
Debug Information and TASM
The debug information in some files that contain inline assembler statements may cause
TASM to run out of memory. You can:
1. Try to give TASM more memory.
2. Compile the file outside of the MAKE procedure.
3. Try using MAKER -S to free more real-mode memory for TASM during the MAKE
process.
4. Change SRC\MAKEFILE to spawn TASMX for the offending files. For example,
to compile and assemble SRC\FILE.CPP, add the following line to the end of
SRC\MAKEFILE:
$D\file.obj : file.cpp
$(CPP) $(CFLAGS) -S -n$(D) file.cpp
@tasmx /ml /t $(D)\file.asm,$(D)\file.obj
Memory Model Issues
In medium model, the MFC class library source code relies on a non-standard extension
to member function modifiers. You cannot compile the MFC class library in medium
model with any compiler that does not support this non-standard extension.
In small or compact model, some of the example programs will not link with Borland
C++ 3.1. This is because more of the runtime library is pulled in by the link step. To
run these examples, use a larger memory model.
Building with 386^Max
If you are running the version of 386^Max that comes with MSC/C++ 7.0, version 6.01d,
you may get errors or hangs from 386max's DPMI server while building the MFC class
library or example files. If this happens, insert the following line in the 386MAX.PRO
file in the directory where 386MAX is installled:
NODPMI
This will allow Borland C++ 3.1 to use its own DPMI server and will prevent these
problems.
Building the Example Programs
This section discusses building the MFC sample programs using Borland C++ 3.1. You
will need to make changes to your build process, and in some cases fix syntax errors in
the sample programs.
Changes to the Build Process
To build the sample applications, you will need to copy the TURBOC.CFG from the
MFC\SRC directory. In addition, because the resource compiler does not explicitly path
WINDOWS.H and other header files, you must change the implicit rule in your
BUILTINS.MAK file so that MAKE will include the directory where the headers reside.
For example, if you installed Borland C++ 3.1 in C:\BORLANDC and MSC/C++ 7.0 in
C:\C700, you would change the .rc.res rule to:
.rc.res:
$(RC) $(RFLAGS) /I\borlandc\include;\c700\mfc\include /r $&
Building An Example: ABOUT2
The makefiles for the sample programs follow the same pattern. To build a sample with
Borland C++ 3.1, you will need to change each makefile. The steps for doing this
follow, using ABOUT2 as an example. In addition to changing the makefile, you will
have to change some of the source files.
Note that the examples are all small model examples. If you have built the large model
libary, you must change the makefile to use that library. If you have problems linking
the examples in small model with Borland C++ 3.1, rebuild the library and the example
in large model.
Begin by copying MFC\SRC\TURBOC.CFG into the SAMPLES\ABOUT2 directory.
Remember, you must repeat this step for each example program that you build.
Changes to SAMPLES|ABOUT2\MAKEFILE
1. Replace lines 25-36 with the lines:
!ifdef __TURBOC__
CPPFLAGS= /DWINVER=0x0310 /ms /w /a- /WE /OW /2
LINKFLAGS=/Twe /L\borlandc\lib;\c700\mfc\lib
!if "$(DEBUG)"=="1"
CPPFLAGS=/D_DEBUG $(CPPFLAGS) /Od /v /N
LINKFLAGS=$(LINKFLAGS) /v
LIBS=safxcwd cws
!else
CPPFLAGS=$(CPPFLAGS) /Oselg
LINKFLAGS=$(LINKFLAGS)
LIBS=safxcw cws
!endif
!else
CPPFLAGS= /DWINVER=0x0300 /AS /W3 /Zp /GA /GEs /G2
LINKFLAGS=/NOD /ONERROR:NOEXE
!if "$(DEBUG)"=="1"
CPPFLAGS=/D_DEBUG $(CPPFLAGS) /Od /f /Zi
LINKFLAGS=$(LINKFLAGS) /COD
LIBS=safxcwd libw slibcew
!else
CPPFLAGS=$(CPPFLAGS) /Oselg /Gs
LINKFLAGS=$(LINKFLAGS)
LIBS=safxcw libw slibcew
!endif
!endif
2. Replace line 55 with the lines:
!ifdef __TURBOC__
tlink $(LINKFLAGS) c0ws about2, about2, NUL, $(LIBS),
about2.def;
!else
link $(LINKFLAGS) about2, about2, NUL, $(LIBS), about2.def;
!endif
Changes to SAMPLES\ABOUT2\ABOUT2.H
1. Line 92 has a syntax error. DECLARE_MESSAGE_MAP() cannot be followed by a
semicolon. You should change it to:
90: // Message map defined in the .cpp file.
91: //
92: DECLARE_MESSAGE_MAP()
93: private:
94: short m_nCurrentColor;
95: short m_nCurrentFigure;
96: };
Changes to Other Example Programs
The following describes changes you will need to make to some of the other sample
programs provided with C/C++ 7.0.
Changes to SAMPLES\CTRLTEST\WCLSTEST.CPP
1. Line 26 has a syntax error. DECLARE_MESSAGE_MAP() cannot be followed by a
semicolon. You should change it to:
25: void OnIllegalChar();
26: DECLARE_MESSAGE_MAP()
27: };
Changes to SAMPLES\CTRLTEST\PAREDIT2.CPP
1. Line 41 has a syntax error. DECLARE_MESSAGE_MAP() cannot be followed by a
semicolon. You should change it to:
40: static LONG FAR PASCAL __export WndProcHook(HWND, UINT, UINT,
LONG);
41: DECLARE_MESSAGE_MAP()
Changes to SAMPLES\CTRLTEST\FEATPEN.CPP
1. Lines 38 and 97 have syntax errors. DECLARE_MESSAGE_MAP() cannot be
followed by a semicolon. You should change these lines to:
37: void OnConfigure();
38: DECLARE_MESSAGE_MAP()
39: };
96: void OnChooseInkColor();
97: DECLARE_MESSAGE_MAP()
98:};
Changes to SAMPLES\CTRLTEST\CUSTLIST.CPP
1. Line 121 has a syntax error. DECLARE_MESSAGE_MAP() cannot be followed by
a semicolon. You should change it to:
120: void OnOK();
121: DECLARE_MESSAGE_MAP()
122:};
15